package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 获取分类列表（包含题目数量）
     * @return 分类列表数据
     */
    public List<Category> getCategoriesWithCount() {
        //获取所有分类数据并按照sort字段排序
        List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        List<Category> categories1 = extracted(categories);
        return categories1;
    }

    private List<Category> extracted(List<Category> categories) {
        List<Map<Long, Long>> countList = questionMapper.getCategoryCount();
        Map<Long, Long> countMap = countList.stream().collect(Collectors.toMap(
                m -> m.get("category_id"),
                m -> m.get("count")
        ));
        categories.forEach(
                category -> {
                    Long questionCount = countMap.getOrDefault(category.getId(), 0L);
                    category.setCount(questionCount);
                }
        );
        return categories;
    }

    /**
     * 获取分类树形结构
     * @return 分类树数据
     */
    public List<Category> getCategoryTree() {
        //获取所有分类数据并按照sort字段排序
        List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        //获取题目数量并放入分类中
        List<Category> extracted = extracted(categories);
        //构建树形结构
        List<Category> categoryTree = buildCategoryTree(extracted);
        //将题目数量进行累加
        categoryTree.stream().forEach(c -> {
            //基础的题目数量
            Long count = c.getCount();
            //子分类的题目数量
            Long childrenCount = c.getChildren().stream().mapToLong(l -> l.getCount() != null ? l.getCount() : 0L).sum();
            c.setCount(count + childrenCount);
        });
        return categoryTree;
    }

    private List<Category> buildCategoryTree(List<Category> categories) {
    if (categories == null || categories.isEmpty()) {
        return new ArrayList<>();
    }

    // 构建ID到分类的映射
    Map<Long, Category> categoryMap = categories.stream()
            .collect(Collectors.toMap(Category::getId, Function.identity()));

    // 构建父ID到子分类列表的映射
    Map<Long, List<Category>> parentMap = new HashMap<>();
    for (Category category : categories) {
        Long parentId = category.getParentId();
        if (parentId != null) {
            parentMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(category);
        }
    }

    // 设置每个分类的子分类
    for (Category category : categories) {
        Long id = category.getId();
        List<Category> children = parentMap.getOrDefault(id, new ArrayList<>());
        category.setChildren(children);
    }

    // 返回根节点（parentId为0的分类）
    return categories.stream()
            .filter(category -> category.getParentId() == null || category.getParentId() == 0)
            .collect(Collectors.toList());
}


    /**
     * 添加分类
     * @param category 分类对象
     * @return 操作结果
     */
    public boolean addCategory(Category category) {
        log.info("添加分类：{}", category);
        //判断名称是否已经存在
        Long l = baseMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getName, category.getName())
                .eq(Category::getParentId, category.getParentId()));
        if (l > 0) {
            //已经存在
            Category parent = baseMapper.selectById(category.getParentId());
            throw new RuntimeException("在%s父分类下已存在名称:%s子分类".formatted(parent.getName(), category.getName()));
        } else {
            //不存在
            return baseMapper.insert(category) > 0;
        }
    }

    /**
     * 更新分类
     * @param category 分类对象
     * @return 操作结果
     */
    public boolean updateCategory(Category category) {
        //判断修改的是名称还是名称以外的属性
        Category oldCategory = baseMapper.selectOne(new LambdaQueryWrapper<Category>().eq(Category::getName, category.getName()));
        if (oldCategory == null || oldCategory.getId().equals(category.getId())) {
            //名称没有被修改,修改的是其他属性
            return baseMapper.updateById(category) > 0;
        } else {
            //名称被修改
            //判断名称是否已经存在
            Long l = baseMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getName, category.getName())
                    .eq(Category::getParentId, category.getParentId()));
            if (l > 0) {
                //已经存在
                throw new RuntimeException("在%s父分类下已存在名称:%s子分类".formatted(oldCategory.getName(), category.getName()));
            }
            return baseMapper.updateById(category) > 0;
        }
    }


    /**
     * 删除分类
     * @param id 分类ID
     * @return 操作结果
     */
    public boolean deleteByIds(Long id) {
        //判断是否有子类和题目存在,如果有其中一个将不能删除
        Long l1 = baseMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getParentId, id));
        Long l = questionMapper.selectCount(new LambdaQueryWrapper<Question>().eq(Question::getCategoryId, id));
        if (l1 > 0 || l > 0) {
            throw new RuntimeException("该分类下有子分类或题目，无法删除");
        }
        return baseMapper.deleteById(id) > 0;
    }

} 